import pandas as pd
import numpy as np
from sklearn.decomposition import PCA

def pca_weight(df: pd.DataFrame, columns: list, n_components: int = None) -> pd.Series:
    """
    基于主成分分析（PCA）的权重计算方法

    参数：
        df: 原始DataFrame
        columns: 需要参与PCA的指标列
        n_components: 保留的主成分数量，默认保留全部

    返回：
        pd.Series，索引为指标列名，值为对应权重
    """
    data = df[columns].dropna()  # 处理可能存在的缺失值
    pca = PCA(n_components=n_components)
    pca.fit(data)

    # 获取主成分贡献率（方差解释率）
    var_ratio = pca.explained_variance_ratio_  # shape: (n_components,)
    components = np.abs(pca.components_)       # shape: (n_components, n_features)

    # 计算每个变量的加权得分
    weighted_scores = np.dot(var_ratio, components)  # shape: (n_features,)
    weights = weighted_scores / weighted_scores.sum()  # 归一化为1

    return pd.Series(weights, index=columns, name="PCA_Weight")
